Skip to content

Upgrade to hypersync-client-rust v1.0.1 with new fields and fixes#50

Open
JasoonS wants to merge 1 commit intomainfrom
claude/fix-dns-failover-python-08DXY
Open

Upgrade to hypersync-client-rust v1.0.1 with new fields and fixes#50
JasoonS wants to merge 1 commit intomainfrom
claude/fix-dns-failover-python-08DXY

Conversation

@JasoonS
Copy link
Contributor

@JasoonS JasoonS commented Mar 15, 2026

Summary

This PR upgrades the Python client from hypersync-client-rust v0.17 to v1.0.1, bringing new blockchain data fields, bug fixes, and internal improvements. The upgrade includes support for EIP-4844 blob transactions, Optimism L2 fields, new trace fields, and fixes for Block field mappings.

Key Changes

API Changes

  • Renamed ClientConfig.bearer_token to api_token with backward compatibility support (old name still accepted but deprecated)
  • Added StreamConfig.reverse field to support streaming data in reverse chronological order

New Transaction Fields

  • EIP-4844 blob transaction support: blob_gas_price, blob_gas_used
  • Optimism/L2 fields: deposit_nonce, deposit_receipt_version, l1_base_fee_scalar, l1_blob_base_fee, l1_blob_base_fee_scalar, l1_block_number, mint, source_hash
  • Function signature: sighash

New Trace Fields

  • sighash - 4-byte function signature hash
  • action_address - action address for contract creation traces
  • balance - balance for the trace operation
  • refund_address - refund address for refund operations

New DataType Enum Values

  • DECIMAL256 - 256-bit decimal type
  • DECIMAL128 - 128-bit decimal type

Bug Fixes

  • Fixed Block field mappings: send_count, send_root, and mix_hash now correctly map to their respective fields instead of all mapping to transactions_root
  • Fixed Transaction.chain_id conversion to properly handle byte slice conversion
  • Fixed Transaction.kind field to use type_ field from upstream client

Internal Changes

  • Arrow FFI migration: Replaced polars-arrow with arrow-rs v57 for Arrow integration
  • Updated alloy crates from v0.8 to v1.1 (alloy-json-abi, alloy-dyn-abi, alloy-primitives)
  • Simplified EventResponse handling: Changed from Vec<Vec<Event>> to flat Vec<Event> structure
  • Updated version from 0.9.0 to 0.10.0

Implementation Details

  • The api_token field is now primary in ClientConfig, with bearer_token kept for backward compatibility
  • Arrow FFI conversion refactored to use arrow::ffi_stream::FFI_ArrowArrayStream and RecordBatchIterator instead of polars-arrow's export mechanism
  • Event response conversion simplified to iterate over flat event list instead of nested batches
  • All new fields are optional and additive, maintaining backward compatibility
  • Comprehensive migration guide and changelog added for users upgrading from v0.9

https://claude.ai/code/session_01KKQaiY8uNKsLqKz5eAu1fe

Summary by CodeRabbit

Release Notes

  • New Features

    • Added 11 new transaction fields for EIP-4844 blob data and Layer 2 operations
    • Added 4 new trace fields for enhanced transaction metadata
    • New reverse chronological streaming option
    • Extended data type support with DECIMAL128 and DECIMAL256
  • Bug Fixes

    • Corrected block field mappings for send_count, send_root, and mix_hash
  • Breaking Changes

    • ClientConfig: bearer_token renamed to api_token (backward compatible)

Major upgrade of the underlying Rust client from v0.17 to v1.0.1.

Key changes:
- DNS failover fix: HTTP client now refreshes connections every 60s
  to ensure DNS lookups catch server IP changes during failovers
- Migrated Arrow FFI from polars-arrow (v0.42) to arrow-rs (v57)
- Updated alloy crates from 0.8 to 1.1
- Renamed bearer_token to api_token (backward compat preserved)
- Added new Transaction fields: blob_gas_price, blob_gas_used,
  deposit_nonce, deposit_receipt_version, l1_base_fee_scalar,
  l1_blob_base_fee, l1_blob_base_fee_scalar, l1_block_number,
  mint, sighash, source_hash
- Added new Trace fields: sighash, action_address, balance,
  refund_address
- Added DataType.DECIMAL256 and DataType.DECIMAL128
- Added StreamConfig.reverse for reverse-order streaming
- Fixed Block.send_count, send_root, mix_hash mappings (were
  incorrectly mapped to transactions_root)
- EventResponse data flattened from Vec<Vec<Event>> to Vec<Event>

See CHANGELOG.md and MIGRATION_GUIDE.md for full details.

https://claude.ai/code/session_01KKQaiY8uNKsLqKz5eAu1fe
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 15, 2026

📝 Walkthrough

Walkthrough

Release v0.10.0 upgrades hypersync-client-rust with dependency updates (alloy 1.1, arrow FFI migration from polars-arrow), adds transaction/trace fields for EIP-4844 blobs and L2 chains, renames ClientConfig.bearer_token to api_token with backward compatibility, and fixes block field mappings.

Changes

Cohort / File(s) Summary
Documentation & Release Notes
CHANGELOG.md, MIGRATION_GUIDE.md
Added comprehensive release notes and migration guide for v0.10.0, documenting breaking changes, new fields (Transaction, Trace, DataType), API token rename, block field fixes, and internal architecture updates.
Cargo Dependencies
Cargo.toml
Bumped crate version to 0.10.0; updated alloy crates (0.8 → 1.1); replaced polars-arrow with arrow v57 (with ffi feature); switched hypersync-client to local path dependency; added ruint, num-bigint, and mimalloc dependencies.
Configuration & Authentication
src/config.rs
Added new api_token field to ClientConfig; deprecated bearer_token with backward compatibility migration logic; added reverse field to StreamConfig for reverse chronological streaming.
Data Types & Models
src/types.rs, hypersync/__init__.py
Extended Transaction with 11 new optional fields (blob_gas_price, blob_gas_used, L1 fees, L2 metadata, sighash, source_hash); extended Trace with 4 new fields (sighash, action_address, balance, refund_address); added DECIMAL256/DECIMAL128 DataType values; fixed Block field conversions (send_count, send_root, mix_hash).
Event Response Handling
src/response.rs
Updated EventStream to use hypersync_client::EventResponse directly instead of intermediate QueryResponse; simplified event data conversion from nested loops to single-pass iterator mapping.
Arrow FFI Migration
src/arrow_ffi.rs
Migrated from polars-arrow to arrow-rs: replaced input type from ArrowBatch to arrow::RecordBatch; refactored stream construction to use RecordBatchIterator with FFI_ArrowArrayStream; updated pyarrow type bindings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #44: Relates to ClientConfig authentication field changes—main PR introduces api_token with bearer_token backward compatibility, while this PR updates example code to use bearer_token, requiring alignment.

Poem

🐰 Hopping through versions, tail held high,
Arrow streams dance across the sky,
Blobs and L1 fees in the fold,
Backward compatibility, stories retold,
From zero-nine to zero-ten we leap,
New fields sown, promises to keep!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: upgrading to hypersync-client-rust v1.0.1 with new fields and fixes, which is the primary objective reflected throughout the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-dns-failover-python-08DXY
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Cargo.toml`:
- Line 23: The Cargo.toml currently uses a sibling path dependency for
hypersync-client which breaks clean checkouts; replace the path dependency entry
for hypersync-client with a published crate version (remove the path =
"../hypersync-client-rust/hypersync-client" and add a version = "..." specifier
for the hypersync-client dependency) so builds resolve from crates.io (pick the
appropriate released version for hypersync-client and update any feature flags
if needed).

In `@hypersync/__init__.py`:
- Around line 723-726: The dataclass field order was changed causing
positional-arg breakage: move the api_token field declaration to appear after
bearer_token in the dataclass in hypersync/__init__.py so that the generated
__init__ preserves the original parameter order (keep both fields and their
comments, updating only their order) to maintain backward-compatible positional
argument behavior for ClientConfig (and any other affected dataclass).

In `@src/config.rs`:
- Around line 83-88: The serialized config still contains the deprecated
bearer_token when both tokens exist; update the code that prepares serialization
(the config clone block around api_token and bearer_token) to explicitly
remove/drop the old field before serializing: after you set config.api_token =
config.bearer_token.take() (or if config.api_token.is_some()), ensure
config.bearer_token = None so serde_json::to_vec(&config) will not emit
bearer_token; reference the local variable config and the fields api_token and
bearer_token in your change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8ca00a4a-1a7b-4924-b2ec-bfb6ef11c469

📥 Commits

Reviewing files that changed from the base of the PR and between 8394bf0 and aa2a9b0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • CHANGELOG.md
  • Cargo.toml
  • MIGRATION_GUIDE.md
  • hypersync/__init__.py
  • src/arrow_ffi.rs
  • src/config.rs
  • src/response.rs
  • src/types.rs

alloy-json-abi = "1.1"
alloy-dyn-abi = "1.1"
alloy-primitives = "1.1"
hypersync-client = { path = "../hypersync-client-rust/hypersync-client" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n '^\s*hypersync-client\s*=' Cargo.toml

python - <<'PY'
from pathlib import Path

root = Path('.').resolve()
dep = (root / '../hypersync-client-rust/hypersync-client').resolve()
inside_repo = dep == root or root in dep.parents

print(f"repo_root={root}")
print(f"resolved_dependency_path={dep}")
print(f"exists={dep.exists()}")
print(f"inside_repo={inside_repo}")
PY

Repository: enviodev/hypersync-client-python

Length of output: 291


Don't ship a sibling path dependency in the release manifest.

This dependency only resolves when ../hypersync-client-rust/hypersync-client exists as a sibling directory outside the repository. Clean checkouts lack this directory, breaking source installs, sdists, and wheel builds. Use a published version instead:

-hypersync-client = { path = "../hypersync-client-rust/hypersync-client" }
+hypersync-client = "1.0.1"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
hypersync-client = { path = "../hypersync-client-rust/hypersync-client" }
hypersync-client = "1.0.1"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Cargo.toml` at line 23, The Cargo.toml currently uses a sibling path
dependency for hypersync-client which breaks clean checkouts; replace the path
dependency entry for hypersync-client with a published crate version (remove the
path = "../hypersync-client-rust/hypersync-client" and add a version = "..."
specifier for the hypersync-client dependency) so builds resolve from crates.io
(pick the appropriate released version for hypersync-client and update any
feature flags if needed).

Comment on lines +723 to 726
# HyperSync server API token.
api_token: Optional[str] = None
# Deprecated: use api_token instead. Kept for backward compatibility.
bearer_token: Optional[str] = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python - <<'PY'
from dataclasses import dataclass
from typing import Optional
import inspect

`@dataclass`
class OldClientConfig:
    url: Optional[str] = None
    bearer_token: Optional[str] = None
    http_req_timeout_millis: Optional[int] = None

`@dataclass`
class NewClientConfig:
    url: Optional[str] = None
    api_token: Optional[str] = None
    bearer_token: Optional[str] = None
    http_req_timeout_millis: Optional[int] = None

print("old_signature:", inspect.signature(OldClientConfig))
print("new_signature:", inspect.signature(NewClientConfig))
print("binding_example:", NewClientConfig("u", None, 1000))
PY

Repository: enviodev/hypersync-client-python

Length of output: 483


🏁 Script executed:

cd /tmp && git ls-files | grep -E 'hypersync.*__init__' | head -5

Repository: enviodev/hypersync-client-python

Length of output: 144


🏁 Script executed:

# Find and examine the ClientConfig class definition
rg -A 20 'class ClientConfig' --no-heading

Repository: enviodev/hypersync-client-python

Length of output: 1342


🏁 Script executed:

# Search for ClientConfig(...) positional calls
rg 'ClientConfig\s*\(' -B 2 -A 2

Repository: enviodev/hypersync-client-python

Length of output: 10975


🏁 Script executed:

rg -B 5 'class ClientConfig' hypersync/__init__.py

Repository: enviodev/hypersync-client-python

Length of output: 179


🏁 Script executed:

# Check if there are any positional-style calls (without keywords)
rg 'ClientConfig\s*\(\s*["\']'

Repository: enviodev/hypersync-client-python

Length of output: 144


🏁 Script executed:

# More thorough check for any positional calls - look for patterns like ClientConfig(something, something_else)
rg 'ClientConfig\([^)]*,' --no-heading

Repository: enviodev/hypersync-client-python

Length of output: 58


Add api_token after bearer_token to preserve positional argument compatibility.

@dataclass generates __init__ parameters in field declaration order. Inserting api_token before bearer_token shifts every later positional argument—code like ClientConfig(url, bearer_token_val, http_req_timeout_millis=5000) would misalign. Though the codebase uses only keyword arguments, external users may rely on positional calls.

Backwards-compatible field order
 class ClientConfig:
     """Configuration for the hypersync client."""
 
     # HyperSync server URL.
     url: Optional[str] = None
     # Deprecated: use api_token instead. Kept for backward compatibility.
     bearer_token: Optional[str] = None
+    # HyperSync server API token.
+    api_token: Optional[str] = None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hypersync/__init__.py` around lines 723 - 726, The dataclass field order was
changed causing positional-arg breakage: move the api_token field declaration to
appear after bearer_token in the dataclass in hypersync/__init__.py so that the
generated __init__ preserves the original parameter order (keep both fields and
their comments, updating only their order) to maintain backward-compatible
positional argument behavior for ClientConfig (and any other affected
dataclass).

Comment on lines +83 to +88
// Handle bearer_token → api_token backward compatibility
let mut config = self.clone();
if config.api_token.is_none() && config.bearer_token.is_some() {
config.api_token = config.bearer_token.take();
}
let json = serde_json::to_vec(&config).context("serialize to json")?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Drop bearer_token before serializing the config.

When both token fields are set, this still emits the deprecated bearer_token downstream. That means this code never actually enforces the documented "api_token takes precedence" rule; it only works if the receiver happens to ignore the old field.

Minimal fix
         // Handle bearer_token → api_token backward compatibility
         let mut config = self.clone();
-        if config.api_token.is_none() && config.bearer_token.is_some() {
-            config.api_token = config.bearer_token.take();
-        }
+        if config.api_token.is_none() {
+            config.api_token = config.bearer_token.take();
+        }
+        config.bearer_token = None;
         let json = serde_json::to_vec(&config).context("serialize to json")?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Handle bearer_token → api_token backward compatibility
let mut config = self.clone();
if config.api_token.is_none() && config.bearer_token.is_some() {
config.api_token = config.bearer_token.take();
}
let json = serde_json::to_vec(&config).context("serialize to json")?;
// Handle bearer_token → api_token backward compatibility
let mut config = self.clone();
if config.api_token.is_none() {
config.api_token = config.bearer_token.take();
}
config.bearer_token = None;
let json = serde_json::to_vec(&config).context("serialize to json")?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config.rs` around lines 83 - 88, The serialized config still contains the
deprecated bearer_token when both tokens exist; update the code that prepares
serialization (the config clone block around api_token and bearer_token) to
explicitly remove/drop the old field before serializing: after you set
config.api_token = config.bearer_token.take() (or if
config.api_token.is_some()), ensure config.bearer_token = None so
serde_json::to_vec(&config) will not emit bearer_token; reference the local
variable config and the fields api_token and bearer_token in your change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants